package com.sprouting.personal.controller;

import cn.dev33.satoken.stp.StpUtil;
import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.collection.ListUtil;
import cn.hutool.core.date.DateField;
import cn.hutool.core.date.DatePattern;
import cn.hutool.core.date.DateTime;
import cn.hutool.core.date.DateUtil;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.sprouting.personal.annotations.ApiIdempotent;
import com.sprouting.personal.interfaces.common.Constant;
import com.sprouting.personal.model.common.ResultJson;
import com.sprouting.personal.model.common.jsr.AddGroup;
import com.sprouting.personal.model.common.jsr.UpdGroup;
import com.sprouting.personal.model.entity.*;
import com.sprouting.personal.model.vo.*;
import com.sprouting.personal.service.*;
import com.sprouting.personal.utils.CheckTool;
import com.sprouting.personal.utils.EntityTool;
import com.sprouting.personal.utils.IdTool;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;

import java.math.BigDecimal;
import java.util.*;
import java.util.function.Function;
import java.util.stream.Collectors;

/**
 * 账单
 *
 * @author ：LX（长沙麓谷）
 * @date 创建时间： 2022/12/27 9:31
 */
@RequestMapping("/bill")
@RestController
@Slf4j
public class BillController {

    @Autowired
    private BillingGroupService billingGroupService;
    @Autowired
    private BillService billService;
    @Autowired
    private DictService dictService;
    @Autowired
    private ConfigService configService;
    @Autowired
    private ExpenseMemberService expenseMemberService;


    /**
     * 该接口用来测试的
     * 经过测试
     * 返回的数据为  del_type=0 ORDER BY create_time DESC  自动加上了这些参数
     * @return
     */
    @GetMapping("/getBill")
    public ResultJson getBill(){
        List<Bill> list = billService.list();
        return ResultJson.success(list);
    }



    // -------------------- 自定义 start


    /**
     * 获取自定义每个家庭成员的支出、收入、笔数
     * @return
     */
    @PostMapping("/getCustomExpenditurePerson")
    public ResultJson getCustomExpenditurePerson(BillQuery billQuery){
        if (billQuery == null){
            billQuery = new BillQuery();
        }
        billQuery.setUserId(StpUtil.getLoginIdAsString());
        List<BillUser> list = billService.getExpenditurePersonQuery(billQuery);
        if (CollUtil.isNotEmpty(list)){
            for (BillUser monthExpenses : list){
                if (Constant.DefaultValue.STRING.equals(monthExpenses.getFamilyMemberId())){
                    monthExpenses.setUserName("全家");
                }
                // 计算盈余
                monthExpenses.setSurplus(monthExpenses.getIncome().subtract(monthExpenses.getExpenditure()));
            }

        }
        return ResultJson.success(list);
    }

    /**
     * 获取自定义支出、收入以及笔数
     * @return
     */
    @PostMapping("/getCustomExpenditure")
    public ResultJson getCustomExpenditure(BillQuery billQuery){
        if (billQuery == null){
            billQuery = new BillQuery();
        }
        billQuery.setUserId(StpUtil.getLoginIdAsString());
        BillUsage expenditure = billService.getExpenditureQuery(billQuery);
        if (expenditure == null){
            expenditure = new BillUsage();
            expenditure.setExpenditureNum(0L);
            expenditure.setIncomeNum(0L);
            expenditure.setExpenditure(new BigDecimal(0));
            expenditure.setIncome(new BigDecimal(0));

        }
        return ResultJson.success(expenditure);
    }

    /**
     * 自定义收入分类情况
     * @return
     */
    @PostMapping("/getCustomRevenueClassification")
    public ResultJson getCustomRevenueClassification(BillQuery billQuery){
        if (billQuery == null){
            billQuery = new BillQuery();
        }
        billQuery.setUserId(StpUtil.getLoginIdAsString());
        billQuery.setIncomeOrExpenditure(Constant.RevenueExpense.INCOME);

        List<BillGroupExpenses> percentageGroup = billService.getPercentageGroupQuery(billQuery);
        if (CollUtil.isEmpty(percentageGroup)){
            BillGroupExpenses expenses = new BillGroupExpenses();
            expenses.setSumPrice(new BigDecimal(0));
            expenses.setCountPrice(0L);
            expenses.setTypeId(Constant.DefaultValue.STRING);
            expenses.setTypeName("全家");

            percentageGroup = new ArrayList<>();
            percentageGroup.add(expenses);
        }
        return ResultJson.success(percentageGroup);
    }

    /**
     * 自定义的支出分类情况
     * @return
     */
    @PostMapping("/getCustomExpenditureClassification")
    public ResultJson getCustomExpenditureClassification(BillQuery billQuery){
        if (billQuery == null){
            billQuery = new BillQuery();
        }
        billQuery.setUserId(StpUtil.getLoginIdAsString());
        billQuery.setIncomeOrExpenditure(Constant.RevenueExpense.EXPENDITURE);
        List<BillGroupExpenses> percentageGroup = billService.getPercentageGroupQuery(billQuery);
        if (CollUtil.isEmpty(percentageGroup)){
            BillGroupExpenses expenses = new BillGroupExpenses();
            expenses.setSumPrice(new BigDecimal(0));
            expenses.setCountPrice(0L);
            expenses.setTypeId(Constant.DefaultValue.STRING);
            expenses.setTypeName("全家");

            percentageGroup = new ArrayList<>();
            percentageGroup.add(expenses);
        }
        return ResultJson.success(percentageGroup);
    }

    // -------------------- 自定义 end


    /**
     * 获取账单组支出情况统计（含不入账的账单）
     * @param billGroupId 账单组ID
     * @return
     */
    @PostMapping("getGroupExpenditureInfoEntry")
    public ResultJson getGroupExpenditureInfoEntry(String billGroupId){
        if (CheckTool.checkNull(billGroupId)){
            return ResultJson.errorIllegal();
        }
        BillUsage groupExpenditureInfo = billingGroupService.getGroupExpenditureInfoEntry(billGroupId);
        if (groupExpenditureInfo == null){
            groupExpenditureInfo = new BillUsage();
        }
        if (groupExpenditureInfo.getExpenditure() == null){
            groupExpenditureInfo.setExpenditure(new BigDecimal(0));
        }
        if (groupExpenditureInfo.getExpenditureNum() == null){
            groupExpenditureInfo.setExpenditureNum(0L);
        }
        if (groupExpenditureInfo.getIncome() == null){
            groupExpenditureInfo.setIncome(new BigDecimal(0));
        }
        if (groupExpenditureInfo.getIncomeNum() == null){
            groupExpenditureInfo.setIncomeNum(0L);
        }

        return ResultJson.success(groupExpenditureInfo);
    }

    /**
     * 获取账单组支出情况统计（不含不入账的账单）
     * @param billGroupId 账单组ID
     * @return
     */
    @PostMapping("getGroupExpenditureInfo")
    public ResultJson getGroupExpenditureInfo(String billGroupId){
        if (CheckTool.checkNull(billGroupId)){
            return ResultJson.errorIllegal();
        }
        BillUsage groupExpenditureInfo = billingGroupService.getGroupExpenditureInfo(billGroupId);
        if (groupExpenditureInfo == null){
            groupExpenditureInfo = new BillUsage();
        }
        if (groupExpenditureInfo.getExpenditure() == null){
            groupExpenditureInfo.setExpenditure(new BigDecimal(0));
        }
        if (groupExpenditureInfo.getExpenditureNum() == null){
            groupExpenditureInfo.setExpenditureNum(0L);
        }
        if (groupExpenditureInfo.getIncome() == null){
            groupExpenditureInfo.setIncome(new BigDecimal(0));
        }
        if (groupExpenditureInfo.getIncomeNum() == null){
            groupExpenditureInfo.setIncomeNum(0L);
        }

        return ResultJson.success(groupExpenditureInfo);
    }

    /**
     * 获取总支出、收入以及相应笔数
     * @return
     */
    @GetMapping("/getTotalExpenditure")
    public ResultJson getTotalExpenditure(){
        String userId = StpUtil.getLoginIdAsString();
        BillUsage expenditure = billService.getExpenditure(userId, null, null);
        return ResultJson.success(expenditure);
    }

    /**
     * 总的收入分类情况
     * @return
     */
    @GetMapping("/getTotalRevenueClassification")
    public ResultJson getTotalRevenueClassification(){
        String userId = StpUtil.getLoginIdAsString();
        // 收入情况
        List<BillGroupExpenses> percentageGroup = billService.getPercentageGroup(userId, null, null, Constant.RevenueExpense.INCOME);
        return ResultJson.success(percentageGroup);
    }

    /**
     * 总的支出分类情况
     * @return
     */
    @GetMapping("/getTotalExpenditureClassification")
    public ResultJson getTotalExpenditureClassification(){
        String userId = StpUtil.getLoginIdAsString();
        // 支出情况
        List<BillGroupExpenses> percentageGroup = billService.getPercentageGroup(userId, null, null, Constant.RevenueExpense.EXPENDITURE);
        return ResultJson.success(percentageGroup);
    }

    /**
     * 获取历年支出情况
     * @return
     */
    @GetMapping("/getExpenditureOverYears")
    public ResultJson getExpenditureOverYears(){
        String userId = StpUtil.getLoginIdAsString();
        List<BillYearExpenses> list = billService.getExpenditureOverYears(userId, null, null);
        if (CollUtil.isNotEmpty(list)){
            for (BillYearExpenses monthExpenses : list){
                // 计算盈余
                monthExpenses.setSurplus(monthExpenses.getIncome().subtract(monthExpenses.getExpenditure()));
            }

            List<BillYearExpenses> sortedList = list.stream().sorted(Comparator.comparing(BillYearExpenses::getTimeYear)).collect(Collectors.toList());
            return ResultJson.success(sortedList);
        }

        return ResultJson.success(list);
    }

    /**
     * 获取总的每个家庭成员的支出、收入、笔数
     * @return
     */
    @GetMapping("/getTotalExpenditurePerson")
    public ResultJson getTotalExpenditurePerson(){
        String userId = StpUtil.getLoginIdAsString();
        List<BillUser> list = billService.getExpenditurePerson(userId, null, null);
        if (CollUtil.isNotEmpty(list)){
            for (BillUser monthExpenses : list){
                if (Constant.DefaultValue.STRING.equals(monthExpenses.getFamilyMemberId())){
                    monthExpenses.setUserName("全家");
                }
                // 计算盈余
                monthExpenses.setSurplus(monthExpenses.getIncome().subtract(monthExpenses.getExpenditure()));
            }
        }
        return ResultJson.success(list);
    }

    /**
     * 获取过去12个月每个月的支出、收入情况和笔数
     * 获取收入12个月的情况
     * 获取支出12个月的情况  - 折线图
     * 获取12个月的支出收入笔数 - 折线图
     * 获取月度结余资金，最近12个月的- 盈余
     * @return
     */
    @GetMapping("/getExpendituresForEachMonthYear")
    public ResultJson getExpendituresForEachMonthYear(){
        String userId = StpUtil.getLoginIdAsString();
        Date now = new Date();
        // 像前面偏移12个月
        DateTime dateTime = DateUtil.offsetMonth(now, -12);
        // 偏移后的月开始时间
        DateTime startTime = DateUtil.beginOfMonth(dateTime);
        // 本月的结束时间
        DateTime endTime = DateUtil.endOfMonth(now);
        List<BillMonthExpenses> list = billService.getExpendituresForEachMonthYear(userId, startTime, endTime);
        if (CollUtil.isNotEmpty(list)){
            for (BillMonthExpenses monthExpenses : list){
                // 计算盈余
                monthExpenses.setSurplus(monthExpenses.getIncome().subtract(monthExpenses.getExpenditure()));
            }
        }

        Map<String, BillMonthExpenses> collect = list.stream().collect(Collectors.toMap(BillMonthExpenses::getTimeMonth, Function.identity()));
        // 获取到本月所有的天数
        List<DateTime> dateTimeList = DateUtil.rangeToList(startTime, endTime, DateField.MONTH);

        // 补充的数据
        List<BillMonthExpenses> supplementList = new ArrayList<>();
        for (DateTime date : dateTimeList){
            BillMonthExpenses dailyExpenditure = collect.get(DateUtil.format(date, DatePattern.NORM_MONTH_PATTERN));
            if (dailyExpenditure == null){
                BillMonthExpenses monthExpenses = new BillMonthExpenses();
                monthExpenses.setTimeMonth(DateUtil.format(date, DatePattern.NORM_MONTH_PATTERN));
                monthExpenses.setExpenditureNum(0L);
                monthExpenses.setIncomeNum(0L);
                monthExpenses.setExpenditure(new BigDecimal("0"));
                monthExpenses.setIncome(new BigDecimal("0"));
                monthExpenses.setSurplus(new BigDecimal("0"));
                supplementList.add(monthExpenses);
            }
        }

        list.addAll(supplementList);
        // 排序时间
        List<BillMonthExpenses> sortedList = list.stream().sorted(Comparator.comparing(BillMonthExpenses::getTimeMonth)).collect(Collectors.toList());
        return ResultJson.success(sortedList);
    }

    /**
     * 过去12个月，每月每个人的支出情况
     * @return
     */
    @GetMapping("/getMonthlyExpenditurePerPersonInThePastYear")
    public ResultJson getMonthlyExpenditurePerPersonInThePastYear(){
        String userId = StpUtil.getLoginIdAsString();
        Date now = new Date();
        // 像前面偏移12个月
        DateTime dateTime = DateUtil.offsetMonth(now, -12);
        // 偏移后的月开始时间
        DateTime startTime = DateUtil.beginOfMonth(dateTime);
        // 本月的结束时间
        DateTime endTime = DateUtil.endOfMonth(now);
        List<BillUserMonth> list = billService.getMonthlyExpenditurePerPersonInThePast(userId, startTime, endTime);
        if (CollUtil.isNotEmpty(list)){
            for (BillUserMonth monthExpenses : list){
                if (Constant.DefaultValue.STRING.equals(monthExpenses.getFamilyMemberId())){
                    monthExpenses.setUserName("全家");
                }
                // 计算盈余
                monthExpenses.setSurplus(monthExpenses.getIncome().subtract(monthExpenses.getExpenditure()));
            }
        }

        return ResultJson.success(list);
    }

    /**
     * 获取年度支出、收入，以及相应的笔数
     * @return
     */
    @GetMapping("/getAnnualExpenditure")
    public ResultJson getAnnualExpenditure(){
        String userId = StpUtil.getLoginIdAsString();
        Date now = new Date();
        DateTime dateTimeStart = DateUtil.beginOfYear(now);
        DateTime dateTimeEnd = DateUtil.endOfYear(now);
        BillUsage expenditure = billService.getExpenditure(userId, dateTimeStart, dateTimeEnd);
        return ResultJson.success(expenditure);
    }

    /**
     * 年度收入分类情况
     * @return
     */
    @GetMapping("/getYearRevenueClassification")
    public ResultJson getYearRevenueClassification(){
        String userId = StpUtil.getLoginIdAsString();
        Date now = new Date();
        DateTime dateTimeStart = DateUtil.beginOfYear(now);
        DateTime dateTimeEnd = DateUtil.endOfYear(now);
        List<BillGroupExpenses> percentageGroup = billService.getPercentageGroup(userId, dateTimeStart, dateTimeEnd, Constant.RevenueExpense.INCOME);
        return ResultJson.success(percentageGroup);
    }

    /**
     * 年度的支出分类情况
     * @return
     */
    @GetMapping("/getYearExpenditureClassification")
    public ResultJson getYearExpenditureClassification(){
        String userId = StpUtil.getLoginIdAsString();
        Date now = new Date();
        DateTime dateTimeStart = DateUtil.beginOfYear(now);
        DateTime dateTimeEnd = DateUtil.endOfYear(now);
        List<BillGroupExpenses> percentageGroup = billService.getPercentageGroup(userId, dateTimeStart, dateTimeEnd, Constant.RevenueExpense.EXPENDITURE);
        return ResultJson.success(percentageGroup);
    }

    /**
     * 获取今年每个家庭成员的支出、收入、笔数
     * @return
     */
    @GetMapping("/getYearExpenditurePerson")
    public ResultJson getYearExpenditurePerson(){
        String userId = StpUtil.getLoginIdAsString();
        Date now = new Date();
        DateTime startTime = DateUtil.beginOfYear(now);
        DateTime endTime = DateUtil.endOfYear(now);
        List<BillUser> list = billService.getExpenditurePerson(userId, startTime, endTime);
        if (CollUtil.isNotEmpty(list)){
            for (BillUser monthExpenses : list){
                if (Constant.DefaultValue.STRING.equals(monthExpenses.getFamilyMemberId())){
                    monthExpenses.setUserName("全家");
                }
                // 计算盈余
                monthExpenses.setSurplus(monthExpenses.getIncome().subtract(monthExpenses.getExpenditure()));
            }
        }
        return ResultJson.success(list);
    }

    /**
     * 获取月度支出、收入以及笔数
     * @return
     */
    @GetMapping("/getMonthlyExpenditure")
    public ResultJson getMonthlyExpenditure(){
        String userId = StpUtil.getLoginIdAsString();
        Date now = new Date();
        DateTime dateTimeStart = DateUtil.beginOfMonth(now);
        DateTime dateTimeEnd = DateUtil.endOfMonth(now);
        BillUsage expenditure = billService.getExpenditure(userId, dateTimeStart, dateTimeEnd);
        return ResultJson.success(expenditure);
    }

    /**
     * 月度收入分类情况
     * @return
     */
    @GetMapping("/getMonthlyRevenueClassification")
    public ResultJson getMonthlyRevenueClassification(){
        String userId = StpUtil.getLoginIdAsString();
        Date now = new Date();
        DateTime dateTimeStart = DateUtil.beginOfMonth(now);
        DateTime dateTimeEnd = DateUtil.endOfMonth(now);
        List<BillGroupExpenses> percentageGroup = billService.getPercentageGroup(userId, dateTimeStart, dateTimeEnd, Constant.RevenueExpense.INCOME);
        if (CollUtil.isEmpty(percentageGroup)){
            BillGroupExpenses expenses = new BillGroupExpenses();
            expenses.setSumPrice(new BigDecimal(0));
            expenses.setCountPrice(0L);
            expenses.setTypeId(Constant.DefaultValue.STRING);
            expenses.setTypeName("全家");

            percentageGroup = new ArrayList<>();
            percentageGroup.add(expenses);
        }
        return ResultJson.success(percentageGroup);
    }

    /**
     * 月度的支出分类情况
     * @return
     */
    @GetMapping("/getMonthlyExpenditureClassification")
    public ResultJson getMonthlyExpenditureClassification(){
        String userId = StpUtil.getLoginIdAsString();
        Date now = new Date();
        DateTime dateTimeStart = DateUtil.beginOfMonth(now);
        DateTime dateTimeEnd = DateUtil.endOfMonth(now);
        List<BillGroupExpenses> percentageGroup = billService.getPercentageGroup(userId, dateTimeStart, dateTimeEnd, Constant.RevenueExpense.EXPENDITURE);
        if (CollUtil.isEmpty(percentageGroup)){
            BillGroupExpenses expenses = new BillGroupExpenses();
            expenses.setSumPrice(new BigDecimal(0));
            expenses.setCountPrice(0L);
            expenses.setTypeId(Constant.DefaultValue.STRING);
            expenses.setTypeName("全家");

            percentageGroup = new ArrayList<>();
            percentageGroup.add(expenses);
        }
        return ResultJson.success(percentageGroup);
    }

    /**
     * 获取本月内每天的支出数量和笔数
     * 月度花销总的走势,支出图  - 折线图
     * @return
     */
    @GetMapping("/getMonthlyExpenditureTrend")
    public ResultJson getMonthlyExpenditureTrend(){
        String userId = StpUtil.getLoginIdAsString();
        Date now = new Date();
        DateTime dateTimeStart = DateUtil.beginOfMonth(now);
        DateTime dateTimeEnd = DateUtil.endOfMonth(now);
        List<BillDailyExpenditure> list = billService.getExpenditureTrend(userId, dateTimeStart, dateTimeEnd);
        Map<Date, BillDailyExpenditure> collect = list.stream().collect(Collectors.toMap(BillDailyExpenditure::getTriggerTime, Function.identity()));
        // 获取到本月所有的天数
        List<DateTime> dateTimeList = DateUtil.rangeToList(dateTimeStart, dateTimeEnd, DateField.DAY_OF_MONTH);

        // 补充的数据
        List<BillDailyExpenditure> supplementList = new ArrayList<>();
        for (DateTime dateTime : dateTimeList){
            BillDailyExpenditure dailyExpenditure = collect.get(dateTime);
            if (dailyExpenditure == null){
                BillDailyExpenditure billDailyExpenditure = new BillDailyExpenditure();
                billDailyExpenditure.setTriggerTime(dateTime);
                billDailyExpenditure.setPrice(new BigDecimal("0"));
                billDailyExpenditure.setCountPrice(0L);
                supplementList.add(billDailyExpenditure);
            }
        }

        list.addAll(supplementList);
        // 排序时间
        List<BillDailyExpenditure> sortedList = list.stream().sorted(Comparator.comparing(BillDailyExpenditure::getTriggerTime)).collect(Collectors.toList());
        return ResultJson.success(sortedList);
    }

    /**
     * 获取本月每个家庭成员的支出、收入、笔数
     * @return
     */
    @GetMapping("/getMonthlyExpenditurePerson")
    public ResultJson getMonthlyExpenditurePerson(){
        String userId = StpUtil.getLoginIdAsString();
        Date now = new Date();
        DateTime startTime = DateUtil.beginOfMonth(now);
        DateTime endTime = DateUtil.endOfMonth(now);
        List<BillUser> list = billService.getExpenditurePerson(userId, startTime, endTime);
        if (CollUtil.isNotEmpty(list)){
            for (BillUser monthExpenses : list){
                if (Constant.DefaultValue.STRING.equals(monthExpenses.getFamilyMemberId())){
                    monthExpenses.setUserName("全家");
                }
                // 计算盈余
                monthExpenses.setSurplus(monthExpenses.getIncome().subtract(monthExpenses.getExpenditure()));
            }
        }
        return ResultJson.success(list);
    }










    /**
     * 获取默认的支付方式
     * @return
     */
    // @GetMapping("/getBillPaymentMethod")
    // @ApiIdempotent
    // public ResultJson<Config> getBillPaymentMethod(){
    //     Config config = configService.getConfigByCodeAutomaticCompletion(Constant.ConfigCode.PAYMENT_METHOD, StpUtil.getLoginIdAsString());
    //     return ResultJson.success(config);
    // }

    /**
     * 获取默认的支付位置
     * @return
     */
    @GetMapping("/getBillPaymentLocation")
    @ApiIdempotent
    public ResultJson<Config> getBillPaymentLocation(){
        Config config = configService.getConfigByCodeAutomaticCompletion(Constant.ConfigCode.PAYMENT_LOCATION, StpUtil.getLoginIdAsString());
        return ResultJson.success(config);
    }

    /**
     * 获取账单类型
     * @return
     */
    @GetMapping("/getBillType")
    public ResultJson<List<Dict>> getBillType(){
        List<Dict> dictList = dictService.getType(Constant.RetainDictGroup.BILLING_TYPE, StpUtil.getLoginIdAsString());
        return ResultJson.success(dictList);
    }

    /**
     * 获取最常用的五个类型(增加了，获取7个。基本覆盖最常用的)
     * @return
     */
    @GetMapping("/getMostCommonlyUsedType")
    public ResultJson getMostCommonlyUsedType(){
        List<String> typeList = billService.getMostCommonlyUsedType(StpUtil.getLoginIdAsString());
        if (CollUtil.isEmpty(typeList)){
            return ResultJson.success();
        }

        List<Dict> dictList = dictService.getDictByIdList(typeList);
        return ResultJson.success(dictList);
    }

    /**
     * 统计根据该查询条件得到的收入和支出结果
     * @param billQuery 查询条件
     * @return
     */
    @PostMapping("/getBillCountList")
    public ResultJson getBillCountList(BillQuery billQuery){
        if (billQuery == null){
            billQuery = new BillQuery();
        }
        billQuery.setUserId(StpUtil.getLoginIdAsString());
        return ResultJson.success(billService.getBillCountList(billQuery));
    }

    /**
     * 获取上一次的账单
     * @return
     */
    @PostMapping("/getLastTimeBill")
    public ResultJson getLastTimeBill(){
        BillVo bill = billService.getLastTimeBill(StpUtil.getLoginIdAsString());
        if (bill == null){
            return ResultJson.success();
        }

        // 添加组名称
        if (!Constant.DefaultValue.STRING.equals(bill.getGroupId())){
            List<BillingGroup> billingGroupList = billingGroupService.getBillingGroupByIdList(ListUtil.of(bill.getGroupId()));
            if (CollUtil.isNotEmpty(billingGroupList)){
                bill.setGroupName(billingGroupList.get(0).getName());
            }
        }

        // 添加账单名称
        List<Dict> dictList = dictService.getDictByIdList(ListUtil.of(bill.getTypeId()));
        if (CollUtil.isNotEmpty(dictList)){
            bill.setTypeName(dictList.get(0).getName());
        }

        // 账单使用人
        List<ExpenseMemberVo> expenseMemberVoList = expenseMemberService.getExpenseMemberByBillIdList(ListUtil.of(bill.getId()));
        // 账单ID -> 账单使用人
        Map<String, List<ExpenseMemberVo>> collect = expenseMemberVoList.stream().collect(Collectors.groupingBy(ExpenseMemberVo::getBillId));
        List<ExpenseMemberVo> memberVoList = collect.get(bill.getId());
        List<String> userNameList = new ArrayList<>();
        List<String> userIdList = new ArrayList<>();
        for (ExpenseMemberVo expenseMemberVo : memberVoList){
            if (Constant.DefaultValue.STRING.equals(expenseMemberVo.getFamilyMemberId())){
                userNameList.add("全家");
                userIdList.add(Constant.DefaultValue.STRING);
            } else {
                userNameList.add(expenseMemberVo.getFamilyMemberName());
                userIdList.add(expenseMemberVo.getFamilyMemberId());
            }
        }

        bill.setUserNameList(userNameList);
        bill.setUserIdList(userIdList);
        return ResultJson.success(bill);
    }

    /**
     * 分页查询账单
     * @param page 分页参数
     * @param billQuery 查询参数
     * @return
     */
    @PostMapping("/getBillPageList")
    public ResultJson getBillPageList(Page page, BillQuery billQuery){
        if (billQuery == null){
            billQuery = new BillQuery();
        }
        billQuery.setUserId(StpUtil.getLoginIdAsString());
        Page<BillVo> billPageList = billService.getBillPageList(page, billQuery);
        List<BillVo> records = billPageList.getRecords();
        if (CollUtil.isEmpty(records)){
            return ResultJson.success(billPageList);
        }

        // 添加组名称
        List<String> groupIdList = records.stream().filter(obj -> !Constant.DefaultValue.STRING.equals(obj.getGroupId())).map(BillVo::getGroupId).collect(Collectors.toList());
        if (CollUtil.isNotEmpty(groupIdList)){
            List<BillingGroup> billingGroupList = billingGroupService.getBillingGroupByIdList(groupIdList);
            // 账单组ID -> 账单组名
            Map<String, String> collect = billingGroupList.stream().collect(Collectors.toMap(BillingGroup::getId, BillingGroup::getName));
            for (BillVo billVo : records){
                billVo.setGroupName(collect.get(billVo.getGroupId()));
            }
        }

        // 添加账单名称
        List<String> typeIdList = records.stream().map(BillVo::getTypeId).collect(Collectors.toList());
        if (CollUtil.isNotEmpty(typeIdList)){
            List<Dict> dictList = dictService.getDictByIdList(typeIdList);
            Map<String, String> collect = dictList.stream().collect(Collectors.toMap(Dict::getId, Dict::getName));
            for (BillVo billVo : records){
                billVo.setTypeName(collect.get(billVo.getTypeId()));
            }
        }

        // 账单使用人
        List<String> idList = records.stream().map(BillVo::getId).collect(Collectors.toList());
        List<ExpenseMemberVo> expenseMemberVoList = expenseMemberService.getExpenseMemberByBillIdList(idList);
        // 账单ID -> 账单使用人
        Map<String, List<ExpenseMemberVo>> collect = expenseMemberVoList.stream().collect(Collectors.groupingBy(ExpenseMemberVo::getBillId));
        for (BillVo billVo : records){
            List<ExpenseMemberVo> memberVoList = collect.get(billVo.getId());
            List<String> userNameList = new ArrayList<>();
            List<String> userIdList = new ArrayList<>();
            for (ExpenseMemberVo expenseMemberVo : memberVoList){
                if (Constant.DefaultValue.STRING.equals(expenseMemberVo.getFamilyMemberId())){
                    userNameList.add("全家");
                    userIdList.add(Constant.DefaultValue.STRING);
                } else {
                    userNameList.add(expenseMemberVo.getFamilyMemberName());
                    userIdList.add(expenseMemberVo.getFamilyMemberId());
                }
            }

            billVo.setUserNameList(userNameList);
            billVo.setUserIdList(userIdList);
        }

        return ResultJson.success(billPageList);
    }

    /**
     * 删除账单
     * @param id 账单ID
     */
    @PostMapping("/delBill")
    @ApiIdempotent
    public ResultJson delBill(String id){
        if (CheckTool.checkNull(id)){
            return ResultJson.errorIllegal();
        }
        billService.delBill(id);
        return ResultJson.success();
    }

    /**
     * 更新账单
     * @param bill 账单
     * @param userIdList 使用人
     * @return
     */
    @PostMapping("/updBill")
    @ApiIdempotent
    public ResultJson updBill(@Validated(UpdGroup.class) Bill bill,  @RequestParam(required = false, value = "userIdSet") Set<String> userIdList){
        String msg = checkBill(bill);
        if (msg != null){
            return ResultJson.error(msg);
        }
        if (CollUtil.isEmpty(userIdList)){
            return ResultJson.error("请指定使用人员信息");
        }

        EntityTool.buildUpdBase(bill, StpUtil.getLoginIdAsString());
        // 资金使用人
        List<ExpenseMember> expenseMemberList = buildExpenseMember(bill, userIdList);
        billService.updBill(bill, expenseMemberList);
        return ResultJson.success();
    }

    /**
     * 新增账单
     * @param bill 账单
     * @param userIdList 使用人，-1默认为全家
     * @return
     */
    @PostMapping("/saveBill")
    @ApiIdempotent
    public ResultJson saveBill(@Validated(AddGroup.class) Bill bill, @RequestParam(required = false, value = "userIdSet") Set<String> userIdList){
        String msg = checkBill(bill);
        if (msg != null){
            return ResultJson.error(msg);
        }
        if (CollUtil.isEmpty(userIdList)){
            return ResultJson.error("请指定使用人员信息");
        }

        // 账单
        bill.setId(IdTool.getId());
        bill.setUserId(StpUtil.getLoginIdAsString());
        EntityTool.buildSaveBase(bill, StpUtil.getLoginIdAsString());
        // 资金使用人
        List<ExpenseMember> expenseMemberList = buildExpenseMember(bill, userIdList);

        billService.saveBill(bill, expenseMemberList);
        return ResultJson.success();
    }

    /**
     * 根据账单组ID查询绑定的账单
     * @param id 账单组ID
     * @param page 分页参数
     * @return
     */
    @PostMapping("/getBillingGroupBindingBill")
    public ResultJson getBillingGroupBindingBill(Page page, String id){
        Page<Bill> billList = billService.getBillByGroupId(page, id);
        return ResultJson.success(billList);
    }

    /**
     * 分页查询账单组
     * @param page 分页参数
     * @param name 查询参数，账单组名称,非必填
     * @param viewInfo 是否展示
     * @return
     */
    @PostMapping("/getBillingGroupPageList")
    public ResultJson getBillingGroupPageList(Page page, String name, String viewInfo){
        String userId = StpUtil.getLoginIdAsString();
        return ResultJson.success(billingGroupService.getBillingGroupPageList(page, name, userId, viewInfo));
    }

    /**
     * 不分页查询全部的账单组
     * @return
     */
    @GetMapping("/getBillingGroupList")
    public ResultJson getBillingGroupList(){
        String userId = StpUtil.getLoginIdAsString();
        return ResultJson.success(billingGroupService.getBillingGroupList(userId));
    }

    /**
     * 保存账单组
     * @param billingGroup 账单组信息
     * @return
     */
    @PostMapping("/saveBillingGroup")
    @ApiIdempotent
    public ResultJson saveBillingGroup(@Validated(AddGroup.class) BillingGroup billingGroup){
        String msg = checkBillingGroup(billingGroup);
        if (msg != null){
            return ResultJson.error(msg);
        }

        if (billingGroup.getImportance() == null){
            billingGroup.setImportance(Constant.Importance.ORDINARY);
        }
        billingGroup.setId(IdTool.getId());
        billingGroup.setUserId(StpUtil.getLoginIdAsString());
        EntityTool.buildSaveBase(billingGroup, StpUtil.getLoginIdAsString());
        billingGroupService.save(billingGroup);

        return ResultJson.success();
    }

    /**
     * 一键解绑
     * @param id 账单组ID
     * @return
     */
    @PostMapping("/oneClickUnbinding")
    @ApiIdempotent
    public ResultJson oneClickUnbinding(String id){
        if (CheckTool.checkNull(id)){
            return ResultJson.errorIllegal();
        }

        billService.updBillUnbinding(id, StpUtil.getLoginIdAsString(), new Date());
        return ResultJson.success();
    }

    /**
     * 根据ID删除账单组
     * @param id 主键
     * @return
     */
    @PostMapping("/delBillingGroup")
    @ApiIdempotent
    public ResultJson delBillingGroup(String id){
        if (CheckTool.checkNull(id)){
            return ResultJson.errorIllegal();
        }

        Bill bill = billService.getBillByGroupIdLimit1(id);
        if (bill != null){
            return ResultJson.error("账单组已绑定数据，请先解绑");
        }

        billingGroupService.removeById(id);
        return ResultJson.success();
    }


    /**
     * 更新账单组
     * @param billingGroup 账单组信息。
     * @return
     */
    @PostMapping("/updBillingGroup")
    @ApiIdempotent
    public ResultJson updBillingGroup(@Validated(UpdGroup.class) BillingGroup billingGroup){
        String msg = checkBillingGroup(billingGroup);
        if (msg != null){
            return ResultJson.error(msg);
        }

        EntityTool.buildUpdBase(billingGroup, StpUtil.getLoginIdAsString());
        billingGroupService.updateById(billingGroup);
        return ResultJson.success();
    }

    /**
     * 校验账单组
     * @param billingGroup 账单组信息
     * @return
     */
    private String checkBillingGroup(BillingGroup billingGroup){
        BillingGroup db = billingGroupService.getBillingGroupByName(billingGroup.getId(), billingGroup.getUserId(), billingGroup.getName());
        if (db != null){
            return "账单组名称已使用，请勿重复添加";
        }

        return null;
    }

    /**
     * 校验账单 + 补充数据
     * @param bill 账单
     * @return 非null则有异常
     */
    private String checkBill(Bill bill){
        if (bill.getTriggerTime() == null){
            return "请输入款项发生时间";
        }
        if (bill.getPrice() == null){
            return "请输入价格";
        }
        BigDecimal price = bill.getPrice();
        if (price.compareTo(BigDecimal.ZERO) == 0){
            return "价格不能为0";
        }
        if (price.compareTo(BigDecimal.ZERO) < 0){
            return "价格不能为负数";
        }

        // 添加默认值
        if (CheckTool.checkNull(bill.getGroupId())){
            bill.setGroupId(Constant.DefaultValue.STRING);
        }
        if (bill.getEntry() == null){
            bill.setEntry(Constant.YesOrNo.YES);
        }
        if (bill.getCore() == null){
            bill.setCore(Constant.YesOrNo.NO);
        }
        if (bill.getModeOfExpenditure() == null){
            bill.setModeOfExpenditure(Constant.ExpenditureType.ON_LINE);
        }

        return null;
    }

    /**
     * 构建生成账单
     * @param bill 账单
     * @param userIdList 使用人
     * @return
     */
    private List<ExpenseMember> buildExpenseMember(Bill bill, Set<String> userIdList){
        List<ExpenseMember> expenseMemberList = new ArrayList<>();
        if (userIdList.contains(Constant.DefaultValue.STRING)){
            // 表示是全家,这里单独写，就是防止出现脏数据还要判断一次
            ExpenseMember expenseMember = new ExpenseMember();
            expenseMember.setId(IdTool.getId());
            expenseMember.setBillId(bill.getId());
            expenseMember.setUserId(StpUtil.getLoginIdAsString());
            expenseMember.setFamilyMemberId(Constant.DefaultValue.STRING);
            EntityTool.buildSaveBase(expenseMember, StpUtil.getLoginIdAsString());
            expenseMemberList.add(expenseMember);

        } else {
            for (String str : userIdList){
                ExpenseMember expenseMember = new ExpenseMember();
                expenseMember.setId(IdTool.getId());
                expenseMember.setBillId(bill.getId());
                expenseMember.setUserId(StpUtil.getLoginIdAsString());
                expenseMember.setFamilyMemberId(str);
                EntityTool.buildSaveBase(expenseMember, StpUtil.getLoginIdAsString());
                expenseMemberList.add(expenseMember);
            }
        }

        return expenseMemberList;
    }
}
